package org.thanos.demo.config;

import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.thanos.demo.processor.TaskProcessor;
import org.thanos.demo.service.TaskService;
import org.thanos.demo.util.SpringUtil;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static org.thanos.demo.constants.DynamicTaskConstants.*;

@Data
@Slf4j
public class DynamicTask implements Runnable {

    private static final ExecutorService es = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(WORK_QUEUE_CAPACITY),
            new DynamicTaskConsumeThreadFactory());

    private Integer id;
    private String taskName;
    private String processor;
    private String param;
    private String cron;
    private Long interval;
    private Long initialDelay;

    private TaskProcessor basicProcessor;

    public void setTaskName(Integer taskId) {
        this.taskName = TASK_PREFIX + taskId;
    }

    @Resource
    private DynamicTaskConfigurer dynamicTaskConfigurer;

    @Resource
    private TaskService taskService;

    @Override
    public void run() {
        log.debug("当前Task: " + this);
        DynamicTaskQueue queue = new DynamicTaskQueue(DYNAMIC_BLOCKING_QUEUE_CAPACITY);
        es.submit(() -> {
            while (!queue.isDone() || !queue.isEmpty()) {
                try {
                    String content = queue.poll(DYNAMIC_BLOCKING_QUEUE_TIMEOUT, TimeUnit.MILLISECONDS);
                    if (StringUtils.isEmpty(content)) {
                        return;
                    }
                    log.debug("DynamicBlockingQueue 消费：" + content);
                    processorExecute();
                } catch (InterruptedException e) {
                    log.error("队列消费数据失败， task:[{}]", this, e);
                    Thread.currentThread().interrupt();
                }
            }
        });

        //队列放入数据
        try {
            queue.put(getTaskName());
            log.debug("DynamicBlockingQueue 生产：" + getTaskName());
        } catch (InterruptedException e) {
            log.error("队列放入数据失败， task:[{}]", this, e);
            Thread.currentThread().interrupt();
        }
        queue.setDone(true);
    }

    private void processorExecute() throws InterruptedException {
        try {
            basicProcessor = SpringUtil.getBean(processor);
            basicProcessor.execute(param);
            TimeUnit.MILLISECONDS.sleep(DYNAMIC_BLOCKING_QUEUE_TIMEOUT);
        } catch (ClassNotFoundException e) {
            log.error("未找到 taskId [{}] 执行器，即将终止该任务", id);
            dynamicTaskConfigurer.removeTaskFromQueue(id);
            log.debug("将任务状态修改为未启用");
            taskService.disableTask(id);
        }
    }
}
